﻿using System;
using System.IO;
using UnityEditor;
using UnityEngine;
using System.Collections.Generic;
using ExcelDataReader;
using System.Data;
using Newtonsoft.Json;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
namespace Client.Editor
{
    public class Export_GameConfig : EditorWindow
    {
        private string excelPath = "";
        private bool existPath = true;
        private string[] excelFiles;
        private string savePath;
        Assembly assembly;
        private bool isEncrypt = false;
        private bool IsEncrypt
        {
            get
            {
                if (!PlayerPrefs.HasKey("ConfigEncrypt_Game"))
                {
                    PlayerPrefs.SetInt("ConfigEncrypt_Game", 0);
                    PlayerPrefs.Save();
                }
                isEncrypt = PlayerPrefs.GetInt("ConfigEncrypt_Game") == 1;
                return isEncrypt;
            }
            set
            {
                if (value != isEncrypt)
                {
                    isEncrypt = value;
                    int v = isEncrypt ? 1 : 0;
                    PlayerPrefs.SetInt("ConfigEncrypt_Game", v);
                    PlayerPrefs.Save();
                }
            }
        }
        public static void ShowWindow()
        {
            // 创建并显示窗口
            Export_GameConfig window = GetWindow<Export_GameConfig>("导出游戏配置"); // 设置窗口的标题
            window.Show();
        }

        private void OnEnable()
        {
            savePath = Path.Combine(Path.GetDirectoryName(Application.dataPath),"Assets", "AssetsBundle", "pk_game", "config");
            assembly = Assembly.Load("CHotFix");
            //获取夫目录
            excelPath = Path.Combine(Path.GetDirectoryName(Application.dataPath), "Excel", "Game");
            if (!Directory.Exists(excelPath))
            {
                existPath = false;
            }
            else
            {
                excelFiles = Directory.GetFiles(excelPath, "*.xlsx"); // 只获取 .xlsx 文件
                if (excelFiles == null)
                {
                    Debug.LogError($"existPath not exist excel file.");
                }
            }
        }

        private void OnGUI()
        {
            if (!existPath)
            {
                //弹出一个不存在该目标的弹窗，点击确定关闭这个窗口
                // 弹出提示框，告诉用户目录不存在
                EditorUtility.DisplayDialog("目录不存在", $"{excelPath}", "确定");
                Close();
            }
            else
            {
                EditorGUILayout.BeginHorizontal("box");
                GUILayout.Label("路径: " + excelPath);
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.BeginHorizontal("box");
                //GUILayout.Label("是否加密:", GUILayout.Width(60));
                //IsEncrypt = EditorGUILayout.Toggle(IsEncrypt);
                EditorGUILayout.EndHorizontal();
                if (excelFiles != null)
                {
                    foreach (var file in excelFiles)
                    {
                        EditorGUILayout.BeginHorizontal("box");

                        if (GUILayout.Button(Path.GetFileName(file)))
                        {
                            ReadFile(file);
                            AssetDatabase.Refresh();
                        }
                        EditorGUILayout.EndHorizontal();
                    }
                    EditorGUILayout.BeginHorizontal("box");
                    GUI.color = Color.green; // 例如，将按钮颜色设置为绿色
                    if (GUILayout.Button("导出全部"))
                    {
                        foreach (var file in excelFiles)
                        {
                            ReadFile(file);
                        }
                        AssetDatabase.Refresh();
                    }
                    GUI.color = Color.white;
                    EditorGUILayout.EndHorizontal();

                }
            }
        }

        private void ReadFile(string file)
        {

            using (var stream = File.Open(file, FileMode.Open, FileAccess.Read))
            {
                using (var reader = ExcelReaderFactory.CreateReader(stream))
                {
                    // 配置Excel读取选项
                    var excelConfig = new ExcelDataSetConfiguration()
                    {
                        ConfigureDataTable = _ => new ExcelDataTableConfiguration()
                        {
                            UseHeaderRow = true, // 关键设置：使用第一行作为列名
                            FilterRow = rowReader => {
                                // 可选：过滤特定行
                                return true;
                            },
                            FilterColumn = (rowReader, columnIndex) => {
                                // 可选：过滤特定列
                                return true;
                            }
                        }
                    };

                    // 将数据读入 DataSet
                    var result = reader.AsDataSet(excelConfig);

                    if (result.Tables.Count == 0)
                        throw new InvalidOperationException("Excel文件中没有找到对应的表");

                    DataTable table = result.Tables[0];
                    string className = table.TableName;

                    // 加载程序集和类型
                    Type targetType = assembly.GetType($"Client.Hotfix.{className}");
                    if (targetType == null)
                        throw new TypeLoadException($"未找到 Client.Hotfix.{className} 类");

                    // 解析前两行：数据类型和字段说明
                    DataRow typeRow = table.Rows[0]; // 第一行：数据类型定义
                    DataRow descRow = table.Rows[1]; // 第二行：字段说明

                    // 从第三行开始是实际数据
                    int dataStartRow = 2;

                    // 建立列映射
                    var columnDefinitions = new List<ColumnDefinition>();
                    for (int colIdx = 0; colIdx < table.Columns.Count; colIdx++)
                    {
                        string typeDef = typeRow[colIdx]?.ToString().Trim();
                        string fieldDesc = descRow[colIdx]?.ToString().Trim();

                        if (string.IsNullOrEmpty(typeDef) || string.IsNullOrEmpty(fieldDesc))
                            continue;

                        columnDefinitions.Add(new ColumnDefinition
                        {
                            index = colIdx,
                            type = typeDef,
                            property = table.Columns[colIdx].ColumnName // 默认列名
                        });
                    }

                    // 动态映射列到属性
                    var propertyMap = new Dictionary<string, PropertyMapping>();
                    var properties = targetType.GetProperties(BindingFlags.Public | BindingFlags.Instance);

                    foreach (var colDef in columnDefinitions)
                    {
                        // 从字段说明中提取可能的属性名（示例逻辑，根据实际情况调整）
                        string potentialPropName = ExtractPropertyName(colDef.property);

                        PropertyInfo property = properties.FirstOrDefault(p =>
                            p.Name.Equals(potentialPropName, StringComparison.OrdinalIgnoreCase));

                        if (property != null)
                        {
                               propertyMap[colDef.property] = new PropertyMapping
                               {
                                    Property = property,
                                    ColumnDefinition  = colDef,
                                    ExpectedType = ParseTypeDefinition(colDef.type)
                                };
                              //Debug.Log($"映射列 {colDef.property} -> {property.Name} ({property.PropertyType.Name})");
                        }
                    }

                    // 读取数据
                    var configs = new List<object>();
                    for (int rowIdx = dataStartRow; rowIdx < table.Rows.Count; rowIdx++)
                    {
                        DataRow row = table.Rows[rowIdx];
                        object configObj = Activator.CreateInstance(targetType);

                        foreach (var mapping in propertyMap)
                        {
                            string colName = mapping.Key;
                            PropertyMapping propMap = mapping.Value;
                            object cellValue = row[propMap.ColumnDefinition.index];

                            try
                            {
                                object convertedValue = ConvertValueByTypeDefinition(cellValue, propMap.ExpectedType, propMap.Property.PropertyType);
                                propMap.Property.SetValue(configObj, convertedValue);
                            }
                            catch (Exception ex)
                            {
                                Debug.LogError($"行 {rowIdx + 1} 列 {colName} 转换失败: {ex.Message}");
                            }
                        }
                        configs.Add(configObj);
                    }

                    string json = JsonConvert.SerializeObject(configs, Formatting.Indented);
                    File.WriteAllText($"{savePath}/{className}.json" , json, System.Text.Encoding.UTF8);
                }
            }
        }
        private Type ParseTypeDefinition(string typeDef)
        {
            if (string.IsNullOrWhiteSpace(typeDef))
                return typeof(object);

            // 先检查复杂类型（字典和数组）
            if (typeDef.StartsWith("<") && typeDef.EndsWith(">"))
            {
                // 字典类型处理
                string innerTypes = typeDef.Trim('<', '>');
                string[] typePair = innerTypes.Split(new[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries);

                if (typePair.Length == 2)
                {
                    Type keyType = ParseBasicType(typePair[0].Trim());
                    Type valueType = ParseBasicType(typePair[1].Trim());

                    if (keyType != null && valueType != null)
                    {
                        return typeof(Dictionary<,>).MakeGenericType(keyType, valueType);
                    }
                }
            }
            else if (typeDef.EndsWith("[]"))
            {
                // 数组类型处理
                string elementTypeStr = typeDef.Substring(0, typeDef.Length - 2);
                Type elementType = ParseBasicType(elementTypeStr);
                return elementType?.MakeArrayType() ?? typeof(object);
            }

            // 基本类型处理
            return ParseBasicType(typeDef) ?? typeof(object);
        }

        private Type ParseBasicType(string typeDef)
        {
            switch (typeDef.ToLower().Trim())
            {
                case "int": return typeof(int);
                case "string": return typeof(string);
                case "bool": return typeof(bool);
                case "integer": return typeof(int);
                case "boolean": return typeof(bool);
                // 添加其他基本类型...
                default: return null;
            }
        }

        private object ConvertValueByTypeDefinition(object value, Type expectedType, Type targetType)
        {
            if (value == null || value is DBNull)
                return targetType.IsValueType ? Activator.CreateInstance(targetType) : null;

            string stringValue = value.ToString();

            try
            {
                // 处理字典类型
                if (expectedType == typeof(Dictionary<int, int>))
                    return ParseIntIntDictionary(stringValue);

                // 处理字典类型
                if (expectedType == typeof(Dictionary<int, string>))
                    return ParseIntStringDictionary(stringValue);

                // 处理字典类型
                if (expectedType == typeof(Dictionary<string, string>))
                    return ParseStringStringDictionary(stringValue);

                // 处理字典类型
                if (expectedType == typeof(Dictionary<int, bool>))
                    return ParseIntBoolDictionary(stringValue);

                // 处理数组类型
                if (targetType.IsArray)
                    return ConvertArray(stringValue, targetType.GetElementType());

                // 基本类型转换
                return Convert.ChangeType(value, targetType);
            }
            catch
            {
                Debug.LogError($"值转换失败: {stringValue} -> {targetType.Name}");
                return targetType.IsValueType ? Activator.CreateInstance(targetType) : null;
            }
        }

        private Dictionary<int, int> ParseIntIntDictionary(string input)
        {
            var dict = new Dictionary<int, int>();
            string[] s1 = input.Split(',');

            foreach (var item in s1)
            {
                string[] s2 = item.Replace("[","").Replace("]","").Split(":", StringSplitOptions.RemoveEmptyEntries);
                if(s2.Length == 2)
                {
                    dict.Add(int.Parse(s2[0]), int.Parse(s2[1]));
                }
            }

            return dict;
        }

        private Dictionary<int, string> ParseIntStringDictionary(string input)
        {
            var dict = new Dictionary<int, string>();
            string[] s1 = input.Split(',');
            foreach (var item in s1)
            {
                string[] s2 = item.Replace("[", "").Replace("]", "").Split(":", StringSplitOptions.RemoveEmptyEntries);
                if (s2.Length == 2)
                {
                    dict.Add(int.Parse(s2[0]), s2[1]);
                }
            }
            return dict;
        }

        private Dictionary<string, string> ParseStringStringDictionary(string input)
        {
            var dict = new Dictionary<string, string>();
            string[] s1 = input.Split(',');
            foreach (var item in s1)
            {
                string[] s2 = item.Replace("[", "").Replace("]", "").Split(":", StringSplitOptions.RemoveEmptyEntries);
                if (s2.Length == 2)
                {
                    dict.Add(s2[0], s2[1]);
                }
            }
            return dict;
        }

        private Dictionary<int, bool> ParseIntBoolDictionary(string input)
        {
            var dict = new Dictionary<int, bool>();
            string[] s1 = input.Split(',');
            foreach (var item in s1)
            {
                string[] s2 = item.Replace("[", "").Replace("]", "").Split(":", StringSplitOptions.RemoveEmptyEntries);
                if (s2.Length == 2)
                {
                    dict.Add(int.Parse(s2[0]),bool.Parse(s2[1]));
                }
            }
            return dict;
        }

        // 辅助类
        private class ColumnDefinition
        {
            public int index { get; set; }
            public string type { get; set; }
            public string property { get; set; }
        }

        private class PropertyMapping
        {
            public ColumnDefinition ColumnDefinition { get; set; }
            public PropertyInfo Property { get; set; }
            public Type ExpectedType { get; set; }
        }

        private string ExtractPropertyName(string fieldDesc)
        {
            // 从字段说明中提取属性名（示例逻辑）
            return fieldDesc.Split(' ').FirstOrDefault()?.Trim();
        }

        private Array ConvertArray(string input, Type elementType)
        {
            if (string.IsNullOrWhiteSpace(input))
                return Array.CreateInstance(elementType, 0);

            var items = input.Split(new[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries)
                            .Select(s => s.Trim())
                            .Where(s => !string.IsNullOrEmpty(s))
                            .ToArray();

            Array array = Array.CreateInstance(elementType, items.Length);

            for (int i = 0; i < items.Length; i++)
            {
                try
                {
                    array.SetValue(Convert.ChangeType(items[i], elementType), i);
                }
                catch
                {
                    array.SetValue(elementType.IsValueType ? Activator.CreateInstance(elementType) : null, i);
                }
            }

            return array;
        }
    }

}


